﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bio.SharedResources.Interfaces;
using Bio.Views.Alignment.ViewModels;
using Bio.Data.Interfaces;
using System.Diagnostics;
using Bio.Data;

namespace Bio.Views.Alignment.Linking
{
    public class LinkedAlignmentViewProxy : ILinkableAlignmentView
    {
        #region ILinkableAlignmentView Members

        public event EventHandler FocusedRowChanged;
        public event EventHandler FocusedColumnIndexChanged;

        public string FocusedRowID
        {
            get { return WrappedVM.FocusedRow.SequenceId; }
        }

        public int FocusedColumnIndex
        {
            get { return WrappedVM.FocusedColumnIndex; }
        }

        public int Columns
        {
            get { return WrappedVM.TotalColumns; }
        }

        public IList<IBioSequence> Rows
        {
            get { return WrappedVM.GroupedEntities; }
        }

        public string Label
        {
            get { return WrappedVM.Title; }
        }

        public string ID { get; private set; }

        public int GetCurrentFocusedSequenceIndex()
        {
            if (!WrappedVM.FocusedRow.IsGroupHeader && 
                WrappedVM.FocusedColumnIndex > 0 && 
                WrappedVM.FocusedColumnIndex >= WrappedVM.FocusedRow.FirstDataIndex &&
                WrappedVM.FocusedRow.AlignedData[WrappedVM.FocusedColumnIndex].Type == BioSymbolType.Nucleotide)
            {
                //We have to determine the zero-based index of the selected nucleotide, and then broadcast that information to any interested structure visualizations.
                int currentNtIndex = Enumerable.Range(WrappedVM.FocusedRow.FirstDataIndex, FocusedColumnIndex - WrappedVM.FocusedRow.FirstDataIndex).Select(i => WrappedVM.FocusedRow.AlignedData[i]).Where(bs => bs.Type == BioSymbolType.Nucleotide).Count();
                return currentNtIndex;
            }

            return -1;
        }

        #endregion

        /// <summary>
        /// Fire the focused row changed event to any linked views.
        /// </summary>
        internal void FireFocusedRowChangedEvent()
        {
            if (FocusedRowChanged != null)
                FocusedRowChanged(this, EventArgs.Empty);
        }

        /// <summary>
        /// Fire the focused column changed event to any rows that are interested, this will be done by the alignment view model
        /// </summary>
        internal void FireFocusedColumnIndexChangedEvent()
        {
            if (FocusedColumnIndexChanged != null)
                FocusedColumnIndexChanged(this, EventArgs.Empty);
        }

        internal LinkedAlignmentViewProxy(AlignmentViewModel wrappedVM)
        {
            Debug.Assert(wrappedVM != null);
            WrappedVM = wrappedVM;
            ID = Guid.NewGuid().ToString();
        }

        private AlignmentViewModel WrappedVM { get; set; }
    }
}
